

Matrix4 = function()
{
	/*******************************************/
	/*				Properties                 */
	/*******************************************/

		this.array = new Array();

		this.m00, this.m01, this.m02, this.m03;
		this.m10, this.m11, this.m12, this.m13;
		this.m20, this.m21, this.m22, this.m23;
		this.m30, this.m31, this.m32, this.m33;

		this.Identity();
}
  
/*********************************/
/*          Methods              */
/*********************************/

	
	Matrix4.prototype.MultMatrix = function(aMatrix )
	{
			var matrix = new Matrix4();

			matrix.array[0]=(this.array[0]*aMatrix.array[0])+(this.array[1]*aMatrix.array[4])+(this.array[2]*aMatrix.array[8])+(this.array[3]*aMatrix.array[12]);
			matrix.array[1]=(this.array[0]*aMatrix.array[1])+(this.array[1]*aMatrix.array[5])+(this.array[2]*aMatrix.array[9])+(this.array[3]*aMatrix.array[13]);
			matrix.array[2]=(this.array[0]*aMatrix.array[2])+(this.array[1]*aMatrix.array[6])+(this.array[2]*aMatrix.array[10])+(this.array[3]*aMatrix.array[14]);
			matrix.array[3]=(this.array[0]*aMatrix.array[3])+(this.array[1]*aMatrix.array[7])+(this.array[2]*aMatrix.array[11])+(this.array[3]*aMatrix.array[15]);

			matrix.array[4]=(this.array[4]*aMatrix.array[0])+(this.array[5]*aMatrix.array[4])+(this.array[6]*aMatrix.array[8])+(this.array[7]*aMatrix.array[12]);
			matrix.array[5]=(this.array[4]*aMatrix.array[1])+(this.array[5]*aMatrix.array[5])+(this.array[6]*aMatrix.array[9])+(this.array[7]*aMatrix.array[13]);
			matrix.array[6]=(this.array[4]*aMatrix.array[2])+(this.array[5]*aMatrix.array[6])+(this.array[6]*aMatrix.array[10])+(this.array[7]*aMatrix.array[14]);
			matrix.array[7]=(this.array[4]*aMatrix.array[3])+(this.array[5]*aMatrix.array[7])+(this.array[6]*aMatrix.array[11])+(this.array[7]*aMatrix.array[15]);

			matrix.array[8]=(this.array[8]*aMatrix.array[0])+(this.array[9]*aMatrix.array[4])+(this.array[10]*aMatrix.array[8])+(this.array[11]*aMatrix.array[12]);
			matrix.array[9]=(this.array[8]*aMatrix.array[1])+(this.array[9]*aMatrix.array[5])+(this.array[10]*aMatrix.array[9])+(this.array[11]*aMatrix.array[13]);
			matrix.array[10]=(this.array[8]*aMatrix.array[2])+(this.array[9]*aMatrix.array[6])+(this.array[10]*aMatrix.array[10])+(this.array[11]*aMatrix.array[14]);
			matrix.array[11]=(this.array[8]*aMatrix.array[3])+(this.array[9]*aMatrix.array[7])+(this.array[10]*aMatrix.array[11])+(this.array[11]*aMatrix.array[15]);

			matrix.array[12]=(this.array[12]*aMatrix.array[0])+(this.array[13]*aMatrix.array[4])+(this.array[14]*aMatrix.array[8])+(this.array[15]*aMatrix.array[12]);
			matrix.array[13]=(this.array[12]*aMatrix.array[1])+(this.array[13]*aMatrix.array[5])+(this.array[14]*aMatrix.array[9])+(this.array[15]*aMatrix.array[13]);
			matrix.array[14]=(this.array[12]*aMatrix.array[2])+(this.array[13]*aMatrix.array[6])+(this.array[14]*aMatrix.array[10])+(this.array[15]*aMatrix.array[14]);
			matrix.array[15]=(this.array[12]*aMatrix.array[3])+(this.array[13]*aMatrix.array[7])+(this.array[14]*aMatrix.array[11])+(this.array[15]*aMatrix.array[15]);

		this.multMatrix = matrix;
		return matrix;
	}
	

       

	/*! brief Set the current matrix to Identity :
	 *
	 *          1   0   0   0
	 *          0   1   0   0
	 *          0   0   1   0
	 *          0   0   0   1
	 */
	Matrix4.prototype.Identity = function()
	{
	    this.array[0]=1; 	this.array[1]=0; 	this.array[2]=0; 	this.array[3]=0;
		this.array[4]=0; 	this.array[5]=1; 	this.array[6]=0; 	this.array[7]=0;
		this.array[8]=0; 	this.array[9]=0; 	this.array[10]=1; 	this.array[11]=0;
		this.array[12]=0;	this.array[13]=0; 	this.array[14]=0; 	this.array[15]=1;
	}
	
	Matrix4.Perspective = function( angle,  ratio,  near,  far)
	{
		this.mat= new Matrix4();

		var f= ((1.0) / (Math.tan(angle / 2.0)));

		this.mat.array[0]=f/ratio; 	this.mat.array[1]=0; 	this.mat.array[2]=0;                         	this.mat.array[3]=0;
		this.mat.array[4]=0; 		this.mat.array[5]=f; 	this.mat.array[6]=0;                         	this.mat.array[7]=0;
		this.mat.array[8]=0; 		this.mat.array[9]=0; 	this.mat.array[10]=((near+far)/(near-far)); 	this.mat.array[11]=((2*near*far)/(near-far));
		this.mat.array[12]=0;		this.mat.array[13]=0; 	this.mat.array[14]=-1;                       	this.mat.array[15]=1;

		return this.mat;
	}
	
	//	An Ortho matrix is divided in 2 operation : A scaling then a Translation 
	Matrix4.Ortho = function( left,  right,  bottom,  top, near, far)
	{
		var matT	= 	new Matrix4();
		var matS	=	new Matrix4();

		
		/*matS.array[0]=2/(right-left); 	matS.array[1]=0; 				matS.array[2]=0;                    matS.array[3]=0;
		matS.array[4]=0; 				matS.array[5]=2/(top-bottom); 	matS.array[6]=0;                   	matS.array[7]=0;
		matS.array[8]=0; 				matS.array[9]=0; 				matS.array[10]=2/(far-near); 		matS.array[11]=0;
		matS.array[12]=0;				matS.array[13]=0; 				matS.array[14]=0;                  	matS.array[15]=1;
		
		matT.array[0]=1; 				matT.array[1]=0; 				matT.array[2]=0;                    matT.array[3]	=-((left+right)/2);
		matT.array[4]=0; 				matT.array[5]=1; 				matT.array[6]=0;                   	matT.array[7]	=-((top+bottom)/2);
		matT.array[8]=0; 				matT.array[9]=0; 				matT.array[10]=1; 					matT.array[11]	=-((near+far)/2);
		matT.array[12]=0;				matT.array[13]=0; 				matT.array[14]=0;                  	matT.array[15]	=1;*/
		
		var r_l	=	right-left;
		var rl = right + left;
		
		var t_p = top-bottom;
		var tp = top + bottom;
		
		var n_f = far - near;
		var nf = near + far;
		
		matS.array[0]=2/(r_l); 			matS.array[1]=0; 				matS.array[2]=0;                    	matS.array[3]= - (rl / r_l);
		matS.array[4]=0; 				matS.array[5]=2/(t_p); 			matS.array[6]=0;                   		matS.array[7]=	-( tp/ t_p);
		matS.array[8]=0; 				matS.array[9]=0; 				matS.array[10]=-2/(n_f); 				matS.array[11]=-	(nf / n_f);
		matS.array[12]=0;				matS.array[13]=0; 				matS.array[14]=0;                  		matS.array[15]=1;
	//	var finalMat = matS.MultMatrix(matT);
		return matS;
	}
	
	/*!	return the matrix formated for uniformMatrix4fv (by columns)	*/
	Matrix4.prototype.AsArray = function()
	{
		var varia = new Array();
		varia[0]=1;
		

		
		varia [0]		=this.array[0]; 				varia[1]	=this.array[4]; 				varia[2]	=this.array[8];							varia[3]	=	this.array[12];
		varia [4]		=this.array[1]; 				varia[5]	=this.array[5]; 				varia[6]	=this.array[9];                   		varia[7]	=	this.array[13];
		varia [8]		=this.array[2]; 				varia[9]	=this.array[6]; 				varia[10]	=this.array[10]; 						varia[11]	=	this.array[14];
		varia [12]	=this.array[3];					varia[13]	=this.array[7]; 				varia[14]	=this.array[11];                  		varia[15]	=	this.array[15];
		
		return varia ;
	}
	Matrix4.prototype.Translate= function( x,  y,  z)
	{
		this.array[3]=x;
		this.array[7]=y;
		this.array[11]=z;
	}
	
	Matrix4.prototype.Print	=	function( )
	{
		return (" "+
				this.array[0] +" "+ this.array[1] +" "+ this.array[2] +" "+ this.array[3] +"\n"+ 
				this.array[4] +" "+ this.array[5] +" "+ this.array[6] +" "+ this.array[7] +"\n"+ 
				this.array[8] +" "+ this.array[9] +" "+ this.array[10] +" "+ this.array[11] +"\n"+ 
				this.array[12] +" "+ this.array[13] +" "+ this.array[14] +" "+ this.array[15] +"\n"
				)
	
	}
	
Matrix4.Translation= function( x,  y,  z)
{
	var mat = new Matrix4();
	mat.Translate(x, y, z);
	return mat;
}
                  